package main

import (
	"fmt"
	"regexp"
	"net/http"
	"io/ioutil"
	"strings"
)

//https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/07.3.md

//regexp包中含有三个函数用来判断是否匹配，如果匹配返回true，否则返回false
//func Match(pattern string, b []byte) (matched bool, error error)
//func MatchReader(pattern string, r io.RuneReader) (matched bool, error error)
//func MatchString(pattern string, s string) (matched bool, error error)
//上面的三个函数实现了同一个功能，就是判断pattern是否和输入源匹配，匹配的话就返回true，
//如果解析正则出错则返回error。三个函数的输入源分别是byte slice、RuneReader和string。

func main(){
	fmt.Println("-----start reg exp test-----")
//	fmt.Println(IsIP("10.96.14.114"))
//	fmt.Println(IsIP("10.96.14.414"))
//	GetWeb()
	regexp_example()
	expand_example()
}

func IsIP(ip string)(b bool){
	if m,_:=regexp.MatchString("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$",ip);!m{
		return false
	}
	return true
}

func GetWeb(){
	resp,err:=http.Get("http://www.baidu.com")
	if err!=nil{
		fmt.Println("http get error",err)
	}
	defer resp.Body.Close()
	body,err:=ioutil.ReadAll(resp.Body)
	if err!=nil{
		fmt.Println("http read error",err)
	}
	
	src:=string(body)
	
	//将HTML标签全转换成小写
	re,_:=regexp.Compile("\\<[\\S\\s]+?\\>")
	src=re.ReplaceAllStringFunc(src,strings.ToLower)
	
	//去除STYLE
	re,_=regexp.Compile("\\<style[\\S\\s]+?\\</style\\>")
	src=re.ReplaceAllString(src,"")
	
	//去除SCRIPT
	re,_=regexp.Compile("\\<script[\\S\\s]+?\\</script\\>")
	src=re.ReplaceAllString(src,"")
	
	//去除所有尖括号内的HTML代码，并换成换行符
	re,_=regexp.Compile("\\<[\\S\\s]+?\\>")
	src=re.ReplaceAllString(src,"\n")
	
	//去除连续的换行符
	re,_=regexp.Compile("\\s{2,}")
	src=re.ReplaceAllString(src,"\n")
	
	fmt.Println(strings.TrimSpace(src))
}

func regexp_example(){
	a:="I am learning Go language"
	
	re,_:=regexp.Compile("[a-z]{2,4}")
	
	//查找符合正则的第一个
	one:=re.Find([]byte(a))
	fmt.Println("Find:",string(one))
	
	//查找符合正则的所有slice,n小于0表示返回全部符合的字符串，不然就是返回指定的长度
	all:=re.FindAll([]byte(a),-1)
	fmt.Println("FindAll",all)
	
	//查找符合条件的index位置,开始位置和结束位置
	index:=re.FindIndex([]byte(a))
	fmt.Println("FindIndex",index)
	
	//查找符合条件的所有的index位置，n同上
	allindex:=re.FindAllIndex([]byte(a),-1)
	fmt.Println("FindAllIndex",allindex)
	
	fmt.Println("--------------------------------")
	re2,_:=regexp.Compile("am(.*)lang(.*)")
	//查找Submatch,返回数组，第一个元素是匹配的全部元素，第二个元素是第一个()里面的，第三个是第二个()里面的
    //下面的输出第一个元素是"am learning Go language"
    //第二个元素是" learning Go "，注意包含空格的输出
    //第三个元素是"uage"
	submatch:=re2.FindSubmatch([]byte(a))
	fmt.Println("FindSubmatch",submatch)
	for _,v:=range submatch {
		fmt.Println(string(v))
	}
	
	//定义和上面的FindIndex一样
	submatchindex:=re2.FindSubmatchIndex([]byte(a))
	fmt.Println("submatchindex:",submatchindex)
	
	//FindAllSubmatch,查找所有符合条件的子匹配
	submatchall:=re2.FindAllSubmatch([]byte(a),-1)
	fmt.Println("submatchall:",submatchall)
	
	//FindAllSubmatchIndex,查找所有字匹配的index
	submatchallindex:=re2.FindAllSubmatchIndex([]byte(a),-1)
	fmt.Println(submatchallindex)
}

func expand_example(){
	fmt.Println("--------expand_example------")
	src:=[]byte(`
		call hello alice
		hello bob
		call hello eve
	`)
	pat:=regexp.MustCompile(`(?m)(call)\s+(?P<cmd>\w+)\s+(?P<arg>.+)\s*$`)
	res:=[]byte{}
	for _,s := range pat.FindAllSubmatchIndex(src,-1){
		res=pat.Expand(res,[]byte("$cmd('$arg')\n"),src,s)
	}
	fmt.Println(string(res))
}